home *** CD-ROM | disk | FTP | other *** search
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- /* |_o_o|\\ Copyright (c) 1986 The Software Distillery. All Rights Reserved */
- /* |. o.| || This program may not be distributed without the permission of */
- /* | . | || the authors. */
- /* | o | || Dave Baker Ed Burnette Stan Chow Jay Denebeim */
- /* | . |// Gordon Keener Jack Rouse John Toebes Doug Walker */
- /* ====== BBS:(919)-471-6436 VOICE:(919)-469-4210 */
- /* */
- /* Contributed to Columbia University for inclusion in C-Kermit. */
- /*
- Permission is granted to any individual or institution to use this
- software as long as it is not sold for profit. This copyright notice must be
- retained. This software may not be included in commercial products without
- written permission of Columbia University.
- */
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /* C K I U T L -- July 17, 1986
- * Utility functions for C-Kermit on the Amiga
- */
-
- #ifndef _lint
- static char *ckuv = "Amiga utility functions, $Id: ckiutl.c,v 1.9 93/08/03 08:37:10 swalton Exp Locker: swalton $";
- #endif
-
- /*
- Author: Jack Rouse, The Software Distillery
-
- The file status routines assume all file protection modes are real, instead
- of just delete protection on files and write protection on disks.
-
- $Log: ckiutl.c,v $
- * Revision 1.9 93/08/03 08:37:10 swalton
- * Changes from Olaf Barthel: Use standard include files and add handling
- * for the NIL: handler
- *
- * Revision 1.8 92/10/30 16:18:58 swalton
- * Added code to call the V37 routine System() rather than the old Execute()
- * routine in the system() utility. It is conditional on the extern int
- * v37 being TRUE. This value is set in ckitio.c.
- *
- * Revision 1.7 92/01/15 17:15:22 swalton
- * Use Id rather than Header in the RCS ID string.
- *
- * Revision 1.6 91/07/18 16:05:28 swalton
- * pipeopen() fixed---it was inadvertently broken somewhere. A system()
- * call was written to replace the no-longer-working Manx one. Both
- * pipeopen() and system() will use the new AmigaOS System() call if
- * the switch V37 was defined to be non-zero when Kermit was compiled.
- *
- * Revision 1.5 91/05/29 09:09:21 swalton
- * 1. Changed function definitions to prototype style. Required adding
- * a few forward declarations.
- * 2. Removed includes of stdio.h, stdlib.h, and string.h, as they are
- * now pulled in by ckcdeb.h, provided we compile with -DCK_ANSILIBS.
- *
- * Revision 1.4 90/11/19 21:47:38 swalton
- * Modifications for compiling with SAS/C Version 5.10, courtesy of
- * Larry Rosenman (ler@lerami.lonestar.org, ler on BIX)
- *
- * Revision 1.3 90/11/07 14:42:33 swalton
- * Version 1.3--released to world as first beta test version simultaneously
- * with release of edit 5A(160).
- *
- * Revision 1.2 90/08/10 10:05:01 swalton
- * A few changes for edit 150 of C Kermit. Also deleted the include of
- * ckipro.h, as it is confusing and somewhat unnecessary right now.
- *
- * Revision 1.1 90/07/12 22:31:24 swalton
- * Minor changes were made to ckiutl.c, mainly to maintain Manx Aztec C
- * compatibility.
- *
- * Revision 1.0 90/04/30 11:54:40 swalton
- * Initial revision
- *
- */
-
- #include "ckcasc.h" /* ASCII symbols */
- #include "ckcdeb.h" /* Debug formats, typedefs, etc. */
- #include "ckcker.h" /* Symbol definitions for Kermit */
- #include <string.h>
-
- #include "exec/types.h"
- #include "exec/exec.h"
- #include "libraries/dos.h"
- #include "libraries/dosextens.h"
- #define fh_Interact fh_Port
- #define fh_Process fh_Type
- #include "fcntl.h"
- #include "signal.h"
-
- #include <clib/exec_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/dos_protos.h>
-
- #if __SASC
- #include <ios1.h>
- #include <time.h>
- #endif
-
-
- #ifdef AZTEC_C
- /* translate Unix file handle (0, 1, or 2) to AmigaDOS file handle */
- #define DOSFH(n) (_devtab[n].fd)
- /* translate Unix file handle (0, 1, or 2) to Aztec file handle */
- #define FILENO(n) (n)
- #endif
- #ifdef __SASC
- #define DOSFH(n) (chkufb(n)->ufbfh)
- #define FILENO(n) (n)
- #endif
-
- /* Amiga Kermit externals (defined in ckitio.c) */
- extern struct Process *CurProc;
- extern struct CommandLineInterface *CurCLI;
-
- /*
- * CreatePacket -- allocate and set up a AmigaDOS packet
- */
- struct DosPacket *
- CreatePacket(void)
- {
- register struct StandardPacket *sp;
-
- sp = (struct StandardPacket *)
- AllocMem((LONG)sizeof(struct StandardPacket),
- (LONG)MEMF_PUBLIC|MEMF_CLEAR);
- if (sp == NULL) return(NULL);
- sp->sp_Pkt.dp_Link = &sp->sp_Msg;
- sp->sp_Msg.mn_Node.ln_Type = NT_MESSAGE;
- sp->sp_Msg.mn_Node.ln_Name = (char *)&sp->sp_Pkt;
- sp->sp_Msg.mn_Length = sizeof(struct DosPacket);
- return(&sp->sp_Pkt);
- }
-
- /*
- * DeletePacket -- deallocate packet from CreatePacket()
- */
- void
- DeletePacket(struct DosPacket *pkt) {
- FreeMem(pkt->dp_Link, (LONG)sizeof(struct StandardPacket));
- }
-
- /*
- * zsyscmd(cmd) -- execute a command.
- * Identical to system except it makes sure that all priveleges are off,
- * so cmd is executed as a system process.
- */
- int system(const char *cmd);
-
- int
- zsyscmd(char *cmd) {
- return(system(cmd));
- }
-
-
-
- /*
- * readstat -- determine file's read status
- * returns -3 if file read protected
- * returns -2 if file is a directory
- * returns -1 if file doesn't exist
- * returns file size otherwise
- */
- long
- readstat(char *name) {
- BPTR lock;
- struct FileInfoBlock *fib;
- long size;
-
- /* locate the file */
- if ((lock = Lock(name, (LONG)ACCESS_READ)) == 0) return(-1);
-
- /* allocate a file info block */
- if ((fib = (struct FileInfoBlock *)malloc(sizeof(*fib))) == NULL)
- { size = -1; goto quit; }
-
- /* make sure it's not a directory */
- if (!Examine(lock, fib) || fib->fib_DirEntryType >= 0)
- { size = -2; goto quit; }
-
- /* make sure it's readable */
- if (fib->fib_Protection & FIBF_READ)
- { size = -3; goto quit; }
-
- size = fib->fib_Size;
- quit:
- if (fib) free(fib);
- UnLock(lock);
- return(size);
- }
-
- /*
- * writestat -- determines file's write status
- * returns 0 if file should be writable, -1 otherwise
- *
- * The following logic is used to determine if a file is writable:
- * 1. If the file exists, it must not be write or delete protected.
- * (Delete protection subsumes write protection for overwriting.)
- * 2. The parent directory must not be write protected ???
- * 3. The volume that the parent directory resides on must be
- * validated and not write protected.
- */
- int
- writestat(char *name) {
- register char *p;
- char *lastslash;
- char path[100];
- BPTR lock;
- struct FileInfoBlock *fib;
- struct InfoData *id = NULL;
- int rc = -1;
-
- /* allocate a FileInfoBlock */
- fib = (struct FileInfoBlock *)malloc(sizeof(*fib));
- if (fib == NULL) goto quit;
-
- /* see if the file exists */
- if ((lock = Lock(name, (LONG)ACCESS_READ)) != 0)
- {
- /* make sure it's not a directory or write protected */
- if (!Examine(lock, fib) ||
- fib->fib_DirEntryType >= 0 ||
- (fib->fib_Protection & (FIBF_WRITE|FIBF_DELETE)) )
- goto quit;
- UnLock(lock);
- } else if (IoErr() == ERROR_ACTION_NOT_KNOWN ||
- stricmp(name, "NIL:") == 0) {
- rc = 0;
- goto quit;
- }
-
- /* strip path from name */
- lastslash = NULL;
- for (p = path; *p = *name; ++p, ++name)
- if (*p == '/' || *p == ':')
- lastslash = p;
-
- /* make sure the path exists */
- if (lastslash)
- {
- lastslash[1] = 0;
- lock = Lock(path, (LONG)ACCESS_READ);
- }
- else
- lock = (CurProc->pr_CurrentDir)
- ? DupLock(CurProc->pr_CurrentDir)
- : 0;
-
- /* make sure it is a directory that is not write protected */
- if (lock == 0 || !Examine(lock, fib) ||
- fib->fib_DirEntryType <= 0 ||
- (fib->fib_Protection & FIBF_WRITE) )
- goto quit;
-
- /* get device info */
- if ((id = (struct InfoData *)malloc(sizeof(*id))) == NULL) goto quit;
-
- /* make sure the disk is writeable */
- if (Info(lock, id) && id->id_DiskState == ID_VALIDATED)
- rc = 0;
-
- /* clean up */
- quit:
- if (id) free(id);
- if (fib) free(fib);
- if (lock) UnLock(lock);
- return(rc);
- }
-
- #include <dos/dostags.h>
-
- static struct TagItem MyTags[] = {
- { SYS_Output, 0L},
- { TAG_END, 0L}
- };
- extern short v37;
-
- /*
- * pipeopen -- execute command to read output like a file
- */
- #define PIPEHOLDER "RAM:Pipe-Holder"
- FILE *
- pipeopen(char *command) {
- BPTR fh;
-
- /* create holder file */
- fh = Open(PIPEHOLDER, (LONG)MODE_NEWFILE);
- if (fh == 0) return(0);
- if (v37) {
- /* execute the command */
- MyTags[0].ti_Data = fh;
- if (System(command, MyTags) != 0)
- return NULL;
- } else
- Execute(command, 0, fh);
-
- /* close the holder file */
- Close(fh);
-
- /* reopen it for input */
- return(fopen(PIPEHOLDER, "r"));
- }
-
- /*
- * pipeclose -- clean up after pipe open
- */
- void
- pipeclose(FILE *f) {
- fclose(f);
- DeleteFile(PIPEHOLDER);
- }
-
- /*
- * existobj -- return true if file system object exists
- */
- int
- existobj(char *name) {
- BPTR lock;
-
- if (*name == 0) return(CurProc->pr_CurrentDir != 0);
- if ((lock = Lock(name, (LONG)ACCESS_READ)) == 0)
- return(0);
- UnLock(lock);
- return(1);
- }
-
- /* opendir handle structure */
- struct DirHandle {
- struct FileInfoBlock fib;
- BPTR lock;
- };
-
- /*
- * attempt to open a directory, fill in a handle structure
- */
- struct DirHandle *
- opendir(char *name) {
- BPTR lock;
- struct DirHandle *dh;
-
- /* get lock on name ("" is current dir) */
- lock = (*name != 0) ? Lock(name, (LONG)ACCESS_READ) :
- (CurProc->pr_CurrentDir) ? DupLock(CurProc->pr_CurrentDir)
- : 0;
- if (lock == 0) return(NULL);
- dh = (struct DirHandle *)malloc(sizeof(*dh));
- if (dh == NULL)
- {
- UnLock(lock);
- return(NULL);
- }
- if (!Examine(lock, &dh->fib) || dh->fib.fib_DirEntryType <= 0)
- {
- UnLock(lock);
- free(dh);
- return(NULL);
- }
- /* pass it into the caller's care */
- dh->lock = lock;
- return(dh);
- }
-
- /*
- * return name for next entry in dir
- */
- char *
- readdir(struct DirHandle *dh) {
- return(ExNext(dh->lock, &dh->fib) ? dh->fib.fib_FileName : NULL);
- }
-
- /*
- * finish accessing a directory
- */
- void
- closedir(struct DirHandle *dh) {
- UnLock(dh->lock);
- free(dh);
- }
- #ifdef __SASC
- /***
- Based on sendpkt.c from AmigaMail Volume 1, Page II-17ff.
-
- ***/
-
- LONG dos_packet(struct MsgPort *pid,LONG action, LONG a1, LONG a2,
- LONG a3, LONG a4, LONG a5,
- LONG a6, LONG a7)
- {
- struct MsgPort *replyport;
- struct StandardPacket *packet;
- LONG res1;
-
- replyport=(struct MsgPort *)CreatePort(NULL,0);
- if (!replyport) return(NULL);
-
- packet=(struct StandardPacket *)
- AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
- if (!packet) {
- DeletePort(replyport);
- return(NULL);
- }
-
- packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
- packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
- packet->sp_Pkt.dp_Port = replyport;
- packet->sp_Pkt.dp_Type = action;
-
- packet->sp_Pkt.dp_Arg1 = a1;
- packet->sp_Pkt.dp_Arg2 = a2;
- packet->sp_Pkt.dp_Arg3 = a3;
- packet->sp_Pkt.dp_Arg4 = a4;
- packet->sp_Pkt.dp_Arg5 = a5;
- packet->sp_Pkt.dp_Arg6 = a6;
- packet->sp_Pkt.dp_Arg7 = a7;
-
-
- PutMsg(pid,(struct Message *)packet);
-
- WaitPort(replyport);
-
- GetMsg(replyport);
-
- res1 = packet->sp_Pkt.dp_Res1;
-
- FreeMem(packet,(long)sizeof(struct StandardPacket));
- DeletePort(replyport);
-
- return(res1);
- }
-
- /* Return 1 if `y' is a leap year, 0 otherwise.
- */
-
- static int
- leap (int y) {
- y += 1900;
- if (y % 400 == 0)
- return (1);
- if (y % 100 == 0)
- return (0);
- return (y % 4 == 0);
- }
-
- /* Return the number of days between Jan 1, 1970 and the given
- * broken-down time.
- */
-
- static int
- ndays (struct tm *p) {
- register n = p->tm_mday;
- register m, y;
- register char *md = "\37\34\37\36\37\36\37\37\36\37\36\37";
-
- for (y = 70; y < p->tm_year; ++y) {
- n += 365;
- if (leap (y)) ++n;
- }
- for (m = 0; m < p->tm_mon; ++m)
- n += md[m] + (m == 1 && leap (y));
- return (n);
- }
-
- /* Convert a broken-down time (such as returned by localtime())
- * back into a `time_t'.
- */
-
- time_t
- mktime(struct tm *tp) {
- register int m1, m2;
- time_t t;
- struct tm otm;
-
- t = (ndays (tp) - 1) * 86400L + tp->tm_hour * 3600L
- + tp->tm_min * 60 + tp->tm_sec;
- /*
- * Now the hard part -- correct for the time zone:
- */
- otm = *tp;
- tp = localtime (&t);
- m1 = tp->tm_hour * 60 + tp->tm_min;
- m2 = otm.tm_hour * 60 + otm.tm_min;
- t -= ((m1 - m2 + 720 + 1440) % 1440 - 720) * 60L;
- return (t);
- }
- #endif
-
- int
- system(const char *command) {
- debug(F110, "system called with command", command, 0L);
- if (v37) {
- MyTags[0].ti_Data = DOSFH(1);
- return(System((UBYTE *) command, MyTags));
- } else {
- Execute((UBYTE *) command, 0, DOSFH(1));
- return 0;
- }
- }
-